function buildRules(ruleTuples) {
    return ruleTuples.map(function (tuple) {
        return {
            name: tuple[0],
            rule: tuple[1],
        };
    });
}

function getOperatingSystemRules() {
    return buildRules([
        ['iOS', /iP(hone|od|ad)/],
        ['Android OS', /Android/],
        ['BlackBerry OS', /BlackBerry|BB10/],
        ['Windows Mobile', /IEMobile/],
        ['Amazon OS', /Kindle/],
        ['Windows 3.11', /Win16/],
        ['Windows 95', /(Windows 95)|(Win95)|(Windows_95)/],
        ['Windows 98', /(Windows 98)|(Win98)/],
        ['Windows 2000', /(Windows NT 5.0)|(Windows 2000)/],
        ['Windows XP', /(Windows NT 5.1)|(Windows XP)/],
        ['Windows Server 2003', /(Windows NT 5.2)/],
        ['Windows Vista', /(Windows NT 6.0)/],
        ['Windows 7', /(Windows NT 6.1)/],
        ['Windows 8', /(Windows NT 6.2)/],
        ['Windows 8.1', /(Windows NT 6.3)/],
        ['Windows 10', /(Windows NT 10.0)/],
        ['Windows ME', /Windows ME/],
        ['Open BSD', /OpenBSD/],
        ['Sun OS', /SunOS/],
        ['Linux', /(Linux)|(X11)/],
        ['Mac OS', /(Mac_PowerPC)|(Macintosh)/],
        ['QNX', /QNX/],
        ['BeOS', /BeOS/],
        ['OS/2', /OS\/2/],
        [
            'Search Bot',
            /(nuhk)|(Googlebot)|(Yammybot)|(Openbot)|(Slurp)|(MSNBot)|(Ask Jeeves\/Teoma)|(ia_archiver)/,
        ],
    ]);
}

function getOSVersion(osName) {
    const ua = navigator.userAgent;
    const match = ua.match(/\d*_\d*_\d*/);
    const versionStr = match && match[0] ? match[0].replace(/_/g, '.') : '';
    switch (osName) {
        case 'Mac OS':
            return versionStr;
        default:
            if (/Windows/.test(osName)) {
                const matchStr = ua.match(/x\d{2}/);
                return matchStr ? matchStr[0] : '';
            }
            return '';
    }
}

export function getOS() {
    const rules = getOperatingSystemRules();
    const userAgentString = navigator.userAgent;
    const detected = rules.filter(function (operation) {
        return operation.rule && operation.rule.test(userAgentString);
    })[0];
    const osInfo = { name: '', version: '' };
    if (detected) {
        osInfo.name = detected.name;
        osInfo.version = getOSVersion(detected.name);
        return osInfo;
    }
    return osInfo;
}

export function getBrowser() {
    const ua = navigator.userAgent.toLowerCase();
    let s;
    if ((s = ua.match(/rv:([\d.]+)\) like gecko/))) {
        return 'IE: ' + s[1];
    } else if ((s = ua.match(/msie ([\d.]+)/))) {
        return 'IE: ' + s[1];
    } else if ((s = ua.match(/edge\/([\d.]+)/))) {
        return 'EDGE: ' + s[1];
    } else if ((s = ua.match(/firefox\/([\d.]+)/))) {
        return 'Firefox: ' + s[1];
    } else if ((s = ua.match(/(?:opera|opr).([\d.]+)/))) {
        return 'Opera: ' + s[1];
    } else if ((s = ua.match(/chrome\/([\d.]+)/))) {
        return 'Chrome: ' + s[1];
    } else if ((s = ua.match(/version\/([\d.]+).*safari/))) {
        return 'Safari: ' + s[1];
    } else {
        return 'Unkonwn';
    }
}

window.browser = getBrowser(),
window.os = getOS().name + getOS().version